Governance as Code: Building Your Trust Ecosystem
This guide introduces key concepts and demonstrates how to programmatically define and manage your trust ecosystem using acapy-cloud's APIs. You'll learn how to:
- Define schemas for credentials
- Create and manage different types of tenants (issuers, verifiers, holders)
- Create credential definitions
- Query and manage the trust registry
The examples use the provided Swagger UI interfaces but can also be automated through direct API calls.
1. Schemas
Schemas are used to define attributes related to credentials. To define schemas for your trust ecosystem, follow the steps below:
- Access the API through the Governance interface.
- Authenticate with
governance.+APIKEYrole. - Generate a new schema with a
POSTto the following API endpoint:/v1/definitions/schemas.
An example of a successful response to generate a DID:
{
"id": "PWmeoVrsLE2pu1idEwWFRW:2:test_schema:0.3.0",
"name": "test_schema",
"version": "0.3.0",
"attribute_names": ["speed"]
}
2. Creating Tenants
In the multi-tenant environment, you can set up issuers, verifiers, and holders. Each tenant gets their own wallet, and the different roles have different privileges.
Issuers
To create an issuer tenant for your trust ecosystem, follow the steps below:
- Access the API through the Multitenant-Admin.
- Authenticate with
tenant-admin.+APIKEYrole. - Create a new tenant with a
POSTto the following API endpoint:/tenant-admin/v1/admin/tenants/, using the example request body below.
{
"wallet_label": "Demo Issuer",
"wallet_name": "Faber",
"roles": ["issuer"],
"group_id": "API demo",
"image_url": "https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png"
}
An example of a successful response to create a new Issuer Tenant:
{
"access_token": "tenant.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRfaWQiOiIwNTYxODM2Mi1iMDI0LTQ2YzUtYjgzYy02YzZiOGM3NzkyZDgiLCJpYXQiOjE3MDAxMjgxNTN9.x_0xa9glFFW44PbfoBiEQY0Lt0dOBLVJgUkdavgusWU",
"wallet_id": "05618362-b024-46c5-b83c-6c6b8c7792d8",
"wallet_label": "Demo Issuer",
"wallet_name": "Faber",
"created_at": "2025-01-16T09:49:13.067595Z",
"updated_at": "2025-01-16T09:49:13.111843Z",
"image_url": "https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png",
"group_id": "API demo"
}
Verifiers
To create a verifier, follow these steps:
-
Access the API through Multitenant-Admin
-
Authenticate using the
tenant-admin.+APIKEYrole -
Generate a new tenant with a
POSTrequest to the API endpoint/tenant-admin/v1/admin/tenants/using the request body detailed in the example below{ "wallet_label": "Demo Verifier", "wallet_name": "Acme", "roles": [ "verifier" ], "group_id": "API demo", "image_url": "https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png" }' -
Below is an example of a successful response to the creation of a new Verifier Tenant:
{ "access_token": "tenant.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRfaWQiOiIwNTYxODM2Mi1iMDI0LTQ2YzUtYjgzYy02YzZiOGM3NzkyZDgiLCJpYXQiOjE3MDAxMjgxNTN9.x_0xa9glFFW44PbfoBiEQY0Lt0dOBLVJgUkdavgusWU", "wallet_id": "05618362-b024-46c5-b83c-6c6b8c7792d8", "wallet_label": "Demo Verifier", "wallet_name": "Acme", "created_at": "2025-01-16T09:49:13.067595Z", "updated_at": "2025-01-16T09:49:13.111843Z", "image_url": "https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png", "group_id": "API demo" }
Holders
Holders are regular tenants without any additional privileges in the Trust Ecosystem. They are created in the same way,
without any roles in the create request
-
Access the API through Multitenant-Admin
-
Authenticate using
tenant-admin.+APIKEYrole -
Generate a new tenant with a
POSTto the API endpoint/tenant-admin/v1/admin/tenants/using the request body in the example below{ "wallet_label": "Demo Holder", "wallet_name": "Alice", "group_id": "API demo", "image_url": "https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png" } -
Here is an example of a successful response to creating a new Holder Tenant:
{ "access_token": "tenant.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRfaWQiOiI0ZTBjNzBmYi1mMmFkLTRmNTktODFmMy05M2Q4ZGY5Yjk3N2EiLCJpYXQiOjE3MDAxMTkzMjJ9.lXrNVWN_bzRXkkBfOd1Yey6D0iqsHpOuXt6aZYwMLp4", "wallet_id": "4e0c70fb-f2ad-4f59-81f3-93d8df9b977a", "wallet_label": "Demo Holder", "wallet_name": "Alice", "created_at": "2025-01-16T07:22:02.086605Z", "updated_at": "2025-01-16T07:22:02.105980Z", "image_url": "https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png", "group_id": "API demo" }
3. Credential Definitions
Credential definitions are expected to be created by all Issuers within the trust ecosystem who wish to issue
credentials to holders. The Trust Authority, which administers the trust ecosystem and enables tenants to write to
the Indy Ledger, acts as the Transaction Endorser of the Trust Ecosystem. Meanwhile, Issuers serve as
Transaction Authors within the Trust Ecosystem. For additional information on Transaction Endorsers and
Transaction Authors, please refer to
Aries Transaction Endorser Support.
To create credential definitions through the Transaction Endorser Protocol for trust ecosystem issuers,
follow the steps below:
-
Access the Tenant Swagger UI
-
Authenticate as an Issuer using
tenant.+JWTKeyx-api-key -
Create a new schema with a
POSTto the API endpoint/v1/definitions/credentialsusing the request body illustrated in the example below.NOTE: The schema ID should already exist in the ledger and be accessible in the Trust Registry
{ "tag": "default", "schema_id": "JPqFhPEM4UiR2ZNK9CM4NA:2:test_schema:0.3.0" } -
Below is an example of a successful response to writing a credential definition:
{ "id": "EfFA6wi7fcZNWzRuHeQqaj:3:CL:8:default", "tag": "default", "schema_id": "JPqFhPEM4UiR2ZNK9CM4NA:2:test_schema:0.3.0" }
4. Trust Registry
To query entries in the Trust Registry, adhere to the following steps:
-
Access the Public Swagger UI
-
Authenticate as an Issuer using
tenant.+JWTKeyroleNOTE: The Trust Registry is currently public and accessible to anyone on the internet
-
The trust-registry has 5 GET endpoints:
-
GET/v1/trust-registry/schemaswill return all schemas on the trust registryResponse:
[ { "did": "GXK1Ubc58DvZDe48zPYdcf", "name": "Proof of Person", "version": "0.1.0", "id": "GXK1Ubc58DvZDe48zPYdcf:2:Proof of Person:0.1.0" }, { "did": "GXK1Ubc58DvZDe48zPYdcf", "name": "Proof of Address", "version": "0.1.0", "id": "GXK1Ubc58DvZDe48zPYdcf:2:Proof of Address:0.1.0" }, { "did": "GXK1Ubc58DvZDe48zPYdcf", "name": "Proof of Medical Aid", "version": "0.1.0", "id": "GXK1Ubc58DvZDe48zPYdcf:2:Proof of Medical Aid:0.1.0" }, { "did": "GXK1Ubc58DvZDe48zPYdcf", "name": "Proof of Bank Account", "version": "0.1.0", "id": "GXK1Ubc58DvZDe48zPYdcf:2:Proof of Bank Account:0.1.0" } ]-
GET/v1/trust-registry/schemas/{schema_id}will return the schema based on id passedResponse:
{ "did": "GXK1Ubc58DvZDe48zPYdcf", "name": "Proof of Bank Account", "version": "0.1.0", "id": "GXK1Ubc58DvZDe48zPYdcf:2:Proof of Bank Account:0.1.0" }-
GET/v1/trust-registry/actorswill return all actors on the trust registry -
Optionally one of the following query parameters can be passed to get a specific actor:
actor_didactor_idactor_name
Response:
[ { "id": "9bdbc626-1499-48e2-a5db-878d347e290b", "name": "[email protected]", "roles": ["issuer"], "did": "did:sov:J1Sg8UHXyuyBCUUpRY3EeZ", "didcomm_invitation": "http://cloudapi.127.0.0.1.nip.io/tenant-admin?oob=eyJAdHlwZSI6ICJodHRwczovL2RpZGNvbW0ub3JnL291dC1...Y29tbS5vcmcvZGlkZXhjaGFuZ2UvMS4wIl19" }, { "id": "fe523496-e0b5-4aea-a038-6ed6cbd686b8", "name": "[email protected]", "roles": ["verifier"], "did": "did:key:z6MkkUK3zRys1WezsaoAtXZtAJrhP7dh5qxbpJMe6cbDcW3s", "didcomm_invitation": "http://cloudapi.127.0.0.1.nip.io/tenant-admin?oob=eyJAdHlwZSI6ICJodHRwczovL2RpZGNvbW0ub3JnL291dC1vZi1iYW...jb21tLm9yZy9kaWRleGNoYW5nZS8xLjAiXX0=" }, { "id": "cf058a03-1f88-4fa9-97dc-96a9cabf8d3e", "name": "Bank Issuer & Verifier", "roles": ["issuer", "verifier"], "did": "did:sov:UhJ5C8hgSiNzpoAYwVcnW9", "didcomm_invitation": "http://cloudapi.127.0.0.1.nip.io/tenant-admin?oob=eyJAdHlwZSI6ICJodHRwczovL2RpZGNvbW0ub3Jn...odHRovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCJdfQ==" } ]GET/v1/trust-registry/actors/issuerswill return all actors withissueras a roleGET/v1/trust-registry/actors/verifierswill return all actors withverifieras a role
-
For how to establish connections, issue credentials, and verify proofs, please refer to the Example Flows guide.